import org.molamil.acto.core.Logger;
import org.molamil.acto.mc.mcw.LcMcWrapper;
import org.molamil.acto.pages.InvalidMcwError;
import org.molamil.acto.pages.MovieContext;
import org.molamil.acto.pages.MovieRequest;
import org.molamil.acto.pages.PagesConf;
import org.molamil.acto.pages.master.AbstractMovieMaster;
import org.molamil.acto.pages.master.ExternalMovieMaster;
import org.molamil.acto.pages.master.InternalMovieMaster;
import org.molamil.acto.pages.master.LinkedMovieMaster;
import org.molamil.acto.pages.master.Master;
import org.molamil.acto.pages.master.MovieMaster;

/**
 * Creates a <code>MovieMaster</code> from a <code>MovieContext</code> object.
 *
 * @author Jorge Hernandez
 */
class org.molamil.acto.pages.MovieBuilder {
	
	
	// Constants
	
	/**
	 * Constant that indicates an external master. 
	 * With value <code>external</code>
	 */
	public static function get TYPE_EXTERNAL():String {return "external";}
	
	/**
	 * Constant that indicates an internal master. 
	 * With value <code>internal</code>
	 */
	public static function get TYPE_INTERNAL():String {return "internal";}
	
	/**
	 * Constant that indicates a linked master. 
	 * With value <code>linked</code>
	 */
	public static function get TYPE_LINKED():String {return "linked";}
	
	
	// Properties
	
	private static var log:Logger = Logger.getLogger("MovieBuilder");
	
	
	// Functions
	
	/**
	 * Creates a <code>MovieMaster</code> from a <code>MovieContext</code> object.
	 * 
	 * @param context <code>MovieContext</code> object holding information to create the new <code>MovieMaster</code>.<br/>
	 * 				  The only required field for is <code>context.name</code><br/>
	 * 				  If no <code>context.type</code> is set, <code>"external"</code> is used.<br/>
	 * 				  If no <code>context.className</code> is set, <code>"org.molamil.acto.mc.mcw.Thin"</code> is used.<br/>
	 * 				  If no the value of <code>context.className</code> is not a fully qualified class name, the classes will 
	 * 				  be looked up in the <code>org.molamil.acto.mc.mcw</code> package.
	 * @throws InvalidMcwError
	 */
	public static function create(context:MovieContext, request:MovieRequest):MovieMaster {
		log.info("create() name = " + context.name);
		var master:AbstractMovieMaster = AbstractMovieMaster(buildMaster(context.type));
		master.mcWrapper = buildMcWrapper(context.className);
		master.context = context;		master.request = request;
		return MovieMaster(master);
	}
	
	private static function buildMaster(type:String):Master {
		log.debug("buildMaster() type = " + type);
		var master:Master;	
		switch (type) {
			case TYPE_LINKED:
				log.debug("the movie is linked");
				master = new LinkedMovieMaster();
				break;
			case TYPE_INTERNAL:
				log.debug("the movie is internal");
				master = new InternalMovieMaster();
				break;
			case TYPE_EXTERNAL:
				log.debug("the movie is external");
				master = new ExternalMovieMaster();
				break;
			default:
				log.info("no type found, external to be used");
				master = new ExternalMovieMaster();
		}
		return master;
	}
	
	private static function buildMcWrapper(className:String):LcMcWrapper {
		log.debug("buildMcWrapper() className = " + className);
		if (className == null || className == "")
			className = PagesConf.defaultMcwClass;
		if (className.indexOf(".") == -1)
			className = PagesConf.defaultMcwPackage + "." + className;
		var f:Function = eval("" + className);
		if (f == null) {
			log.severe("Invalid class name for the MovieClip Wrapper");
			throw new InvalidMcwError();
		}
		return new f();
	}

}